package edu.njit.hz278.core.db;

import java.util.List;

/**
 * IQuery executes basic SQL queries.
 * 
 * @author Rivers Zhang
 * 
 * @param <T>
 */
public interface IQuery<T> {

	/**
	 * Returns a tuple.
	 * 
	 * @param keys
	 *            , composite primary key
	 * @param args
	 * @return
	 */
	T getByKeys(String[] keys, Object[] args);

	/**
	 * Returns a tuple.
	 * 
	 * @param key
	 *            , primary key
	 * @param arg
	 * @return
	 */
	T getByKey(String key, Object arg);

	/**
	 * Returns tuples which satisfy @key IN (args).
	 * 
	 * @param key
	 * @param args
	 * @return
	 */
	List<T> getByKey(String key, Object[] args);

	/**
	 * Returns tuples which satisfy fields[i] = args[i].
	 * 
	 * @param fields
	 * @param args
	 * @param page
	 * @param size
	 * @return
	 */
	List<T> get(String[] fields, Object[] args, int page, int size);

	/**
	 * Returns tuples which satisfy fields[i] = args[i].
	 * 
	 * @param fields
	 * @param args
	 * @return
	 */
	List<T> get(String[] fields, Object[] args);

	/**
	 * Returns tuples which satisfy field = arg.
	 * 
	 * @param field
	 * @param arg
	 * @param page
	 * @param size
	 * @return
	 */
	List<T> get(String field, Object arg, int page, int size);

	/**
	 * Returns tuples which satisfy field = arg.
	 * 
	 * @param field
	 * @param arg
	 * @return
	 */
	List<T> get(String field, Object arg);

	/**
	 * Executes @sql without replacement parameters. Notice that @sql must be
	 * selection statement.
	 * 
	 * @param sql
	 * @return
	 */
	List<T> getBySQL(String sql);

	/**
	 * Executes @sql with replacement parameters. Notice that @sql must be
	 * selection statement.
	 * 
	 * @param sql
	 * @return
	 */
	List<T> getBySQL(String sql, Object... params);

	/**
	 * Executes @sql without replacement parameters. Notice that @sql must be
	 * selection statement.
	 * 
	 * @param sql
	 * @return the 1st matched tuple, if we have any.
	 */
	T getOneBySQL(String sql);

	/**
	 * Executes @sql with replacement parameters. Notice that @sql must be
	 * selection statement.
	 * 
	 * @param sql
	 * @return the 1st matched tuple, if we have any.
	 */
	T getOneBySQL(String sql, Object... params);

	/**
	 * Returns all tuples.
	 * 
	 * @return
	 */
	List<T> list();

	/**
	 * Returns tuples of page @page.
	 * 
	 * @param page
	 * @param size
	 * @return
	 */
	List<T> list(int page, int size);

	/**
	 * Inserts a tuple.
	 * 
	 * @param object
	 * @return the number of affected rows
	 */
	int insert(T object);

	/**
	 * Updates a tuple where @whereAttrs[i] = @object.@whereAttrs[i].
	 * 
	 * @param object
	 * @param whereAttrs
	 * @return the number of affected rows
	 */
	int update(T object, String[] whereAttrs);

	/**
	 * Updates a tuple where @whereAttrs[i] = @object.@whereAttrs[i]. @setAttrs
	 * specifies which columns of the table will be updated.
	 * 
	 * @param object
	 * @param setAttr
	 * @param whereAttrs
	 * @return the number of affected rows
	 */
	int update(T object, String[] setAttrs, String[] whereAttrs);

	/**
	 * Deletes a tuple where @whereAttrs[i] = @object.@whereAttrs[i]. We
	 * recommend only pass in keys as @whereAttrs. Otherwise, this method may
	 * unexpectedly delete other tuples.
	 * 
	 * @param object
	 * @param whereAttrs
	 * @return the number of affected rows
	 */
	int delete(T object, String[] whereAttrs);

	/**
	 * Deletes tuples where @attrs[i] = @args[i].
	 * 
	 * @param attrs
	 * @param args
	 * @return the number of affected rows
	 */
	int delete(String[] attrs, Object[] args);
	
	/**
	 * Deletes tuples where @attr = @arg.
	 * 
	 * @param attrs
	 * @param args
	 * @return the number of affected rows
	 */
	int delete(String attr, Object arg);

	/**
	 * Executes @sql without replacement parameters. Notice that @sql must be
	 * insert/update/delete statements.
	 * 
	 * @param sql
	 * @return the number of affected rows
	 */
	int update(String sql);

	/**
	 * Executes @sql with replacement parameters. Notice that @sql must be
	 * insert/update/delete statements.
	 * 
	 * @param sql
	 * @param params
	 * @return
	 */
	int update(String sql, Object... params);
}
